//
//  Macro_Network.swift
//  Voice
//
//  Created by 卢逢卫 on 2024/3/5.
//

import Network

public class Macro_Network {
    
    public enum Network_Type {

        /// wifi，正在使用Wifi网络
        case wifi

        /// cellular，正在使用蜂窝网络
        case cellular

        /// 网络不可用，请检查网络连接
        case unavailable

        /// 没有网络
        case none

        /// App的网络权限未开启
        case appNetworkDidClose
    }
    // 单例对象
    public static let shared = Macro_Network()

    // 网络切换的回调闭包
    public var changeNetworkBlock: ((_ networkType: Network_Type) -> Void)?

    // 网络监听器
    private var monitor: NWPathMonitor?

    // 开始监听网络状态
    public func listening() {
        monitor = NWPathMonitor()
        let queue = DispatchQueue(label: "com.example.network-monitor")
        monitor?.start(queue: queue)
        monitor?.pathUpdateHandler = { [weak self] path in
            self?.handleNetworkChange(path)
        }
    }

    // 取消监听网络状态
    public func cancel() {
        monitor?.cancel()
        monitor = nil
    }

    // 处理网络状态变化
    // 处理网络状态变化
    private func handleNetworkChange(_ path: NWPath) {
        var networkType: Network_Type = .none

        if path.status == .satisfied {
            if path.usesInterfaceType(.wifi) {
                networkType = .wifi
            } else if path.usesInterfaceType(.cellular) {
                networkType = .cellular
            }
//            else if path.usesInterfaceType(.wiredEthernet) {
//                networkType = .ethernet
//            } else {
//                networkType = .other
//            }
        } else if path.status == .unsatisfied {
            networkType = .unavailable
        } else if path.status == .requiresConnection {
            networkType = .appNetworkDidClose
        } else {
            networkType = .none
        }

        DispatchQueue.main.async {
            self.changeNetworkBlock?(networkType)
        }
    }

    // 判断是否可以联网
    public func canConnectNetwork(block: @escaping (_ connect: Bool) -> Void) {
        let monitor = NWPathMonitor()
        let queue = DispatchQueue(label: "com.example.network-check")
        monitor.start(queue: queue)
        monitor.pathUpdateHandler = { path in
            let canConnect = path.status == .satisfied
            DispatchQueue.main.async {
                block(canConnect)
            }
            monitor.cancel()
        }
    }
}
